/**角色服饰
 * author:noodles
 * 管理服饰资源的加载、解压、更换、呈现
 * 
 * 
 * 
 * */
package com.gamebase.role
{
	import com.gamebase.role.vo.DesignConfigData;
	import com.gamebase.role.vo.DesignPartData;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.geom.Rectangle;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	
	public class Design
	{
		private var partsInfo:Dictionary;
		private var _wholeBMD:BitmapData;
		private var feetLoader:Loader;
		private var legLoader:Loader;
		private var bodyLoader:Loader;
		private var headLoader:Loader;
		private var allLoader:Loader;
		
		private var _all:BitmapData;
		private var _head:BitmapData;
		private var _body:BitmapData;
		private var _leg:BitmapData;
		private var _feet:BitmapData;
		
		private var _allPartByte:ByteArray;
		private var _headPartByte:ByteArray;
		private var _bodyPartByte:ByteArray;
		private var _legPartByte:ByteArray;
		private var _feetPartByte:ByteArray;
		
		private var _allBMDVector:Vector.<Vector.<BitmapData>>;//
		private var _headBMDVector:Vector.<Vector.<BitmapData>>;//
		private var _bodyBMDVector:Vector.<Vector.<BitmapData>>;//
		private var _legBMDVector:Vector.<Vector.<BitmapData>>;//
		private var _feetBMDVector:Vector.<Vector.<BitmapData>>;//
		
		private var _displayObj:Bitmap;
		private var _statusBMDVector:Vector.<Vector.<BitmapData>>;//当前状态位图数据序列
		private var _designConfigData:DesignConfigData;//装配配置数据
		private var _currentLoadData:DesignPartData; // 当前加载的资源信息
		private var _urlLoad:URLLoader;
		private var _maxTryLoadNum:uint;				//加载失败时，最多尝试再加载次数
		private var _rec:Rectangle;						//单帧大小矩形
		private var _currentMoveStatus:String;			//当前移动状态：站立、走、跑等
		
		private var needLoadInfoes:Vector.<DesignPartData>;//需要下载的资源地址列表
		private var loadCallBackFun:Function;//展开资源后的回调
		private var callBackParam:Object;//展开资源后的回调参数
		private var binaryLoadTaskArr:Array;
		private var loadURL:String;//当前下载资源路径
		private var isLoading:Boolean = false;
		
		private var getNum:uint;//需要展开的资源数量
		public var designReadable:Boolean;//true:上次解压完成，可以进行解压，false:上次解压还没有完成
		public var _lock:Boolean;//true:正在加载byteArray数据，或者正在解压
		
		
		
		public function Design()
		{
			_maxTryLoadNum = 5;
			designReadable = true;
			_lock = false;
			_urlLoad = new URLLoader();
			_urlLoad.dataFormat = URLLoaderDataFormat.BINARY;
			_urlLoad.addEventListener(IOErrorEvent.IO_ERROR,loadFail);
			_urlLoad.addEventListener(IOErrorEvent.DISK_ERROR,loadFail);
			_urlLoad.addEventListener(IOErrorEvent.NETWORK_ERROR,loadFail);
			_urlLoad.addEventListener(IOErrorEvent.VERIFY_ERROR,loadFail);
			_urlLoad.addEventListener(ErrorEvent.ERROR,loadFail);
			_urlLoad.addEventListener(SecurityErrorEvent.SECURITY_ERROR,loadSecurityFail);
			_urlLoad.addEventListener(Event.COMPLETE,loaded);
			
			binaryLoadTaskArr= new Array();
			needLoadInfoes = new Vector.<DesignPartData>();
			partsInfo = new Dictionary();
			
		}
		
		/**
		 *加载并解压服装资源 
		 * @param $designConfigData
		 * @param rec
		 * @param defaultMoveStatus： 默认移动状态
		 * @param cb
		 * @param param
		 * 
		 */		
		public function ini($designConfigData:DesignConfigData, rec:Rectangle, defaultMoveStatus:String="Stand", cb:Function=null,param:Object=null):void
		{
			if($designConfigData == null)
			{
				throw new Error("$designConfigData can not be null");
				return;
			}
			
			if(_lock || !designReadable)
			{
				binaryLoadTaskArr.push([$designConfigData,cb,param]);
				return;
			}
			
			_lock = true;
			_rec = rec;
			_currentMoveStatus = defaultMoveStatus;
			loadCallBackFun = cb;
			callBackParam = param;
			if(_designConfigData == null)//首次加载服饰
			{
				_designConfigData = $designConfigData;
				//如果缓存中不存在该状态位图数据系列，则加载并解压获取
				if(DesignBMDCache.hasNoCache(_designConfigData.bmdVectorCacheName+"-"+defaultMoveStatus))
				{
					if($designConfigData.allPartData != null)
					{
						needLoadInfoes.unshift(_designConfigData.allPartData);
					}
					else
					{
						needLoadInfoes.unshift(_designConfigData.headPartData);
						needLoadInfoes.unshift(_designConfigData.bodyPartData);
						needLoadInfoes.unshift(_designConfigData.legPartData);
						needLoadInfoes.unshift(_designConfigData.feetPartData);
					}
				}
				else
				{
					_statusBMDVector = DesignBMDCache.getCache(_designConfigData.bmdVectorCacheName+"-"+defaultMoveStatus);
					onGetStatusBMDVector();
					return;
				}
			}
			else//更新部分服饰
			{
				if($designConfigData.allPartData != null)
				{
					_designConfigData.allPartData = $designConfigData.allPartData;
					//如果缓存中不存在该状态位图数据系列，则加载并解压获取
					if(DesignBMDCache.hasNoCache(_designConfigData.allPartData.bmdVectorCacheName+"-"+defaultMoveStatus))
					{
						needLoadInfoes.unshift(_designConfigData.allPartData);
					}
					else
					{
						_statusBMDVector = _allBMDVector = DesignBMDCache.getCache(_designConfigData.allPartData.bmdVectorCacheName+"-"+defaultMoveStatus);
						onGetStatusBMDVector();
						return;	
					}
				}
				else
				{
					if($designConfigData.feetPartData!=null)
					{
						_designConfigData.feetPartData = $designConfigData.feetPartData;
						//如果缓存中不存在该状态位图数据系列，则加载并解压获取
						if(DesignBMDCache.hasNoCache(_designConfigData.feetPartData.bmdVectorCacheName+"-"+defaultMoveStatus))
						{
							needLoadInfoes.unshift(_designConfigData.feetPartData);
						}
						else
						{
							_feetBMDVector = DesignBMDCache.getCache(_designConfigData.feetPartData.bmdVectorCacheName+"-"+defaultMoveStatus)
						}
					}
					if($designConfigData.legPartData!=null)
					{
						_designConfigData.legPartData = $designConfigData.legPartData;
						//如果缓存中不存在该状态位图数据系列，则加载并解压获取
						if(DesignBMDCache.hasNoCache(_designConfigData.legPartData.bmdVectorCacheName+"-"+defaultMoveStatus))
						{
							needLoadInfoes.unshift(_designConfigData.legPartData);
						}
						else
						{
							_legBMDVector = DesignBMDCache.getCache(_designConfigData.legPartData.bmdVectorCacheName+"-"+defaultMoveStatus)
						}
					}
					if($designConfigData.bodyPartData!=null)
					{
						_designConfigData.bodyPartData = $designConfigData.bodyPartData;
						//如果缓存中不存在该状态位图数据系列，则加载并解压获取
						if(DesignBMDCache.hasNoCache(_designConfigData.bodyPartData.bmdVectorCacheName+"-"+defaultMoveStatus))
						{
							needLoadInfoes.unshift(_designConfigData.bodyPartData);
						}
						else
						{
							_bodyBMDVector = DesignBMDCache.getCache(_designConfigData.bodyPartData.bmdVectorCacheName+"-"+defaultMoveStatus)
						}
					}
					if($designConfigData.headPartData!=null)
					{
						_designConfigData.headPartData = $designConfigData.headPartData;
						//如果缓存中不存在该状态位图数据系列，则加载并解压获取
						if(DesignBMDCache.hasNoCache(_designConfigData.headPartData.bmdVectorCacheName+"-"+defaultMoveStatus))
						{
							needLoadInfoes.unshift(_designConfigData.headPartData);
						}
						else
						{
							_headBMDVector = DesignBMDCache.getCache(_designConfigData.headPartData.bmdVectorCacheName+"-"+defaultMoveStatus)
						}
					}
				}
			}
			if(!isLoading)//不在加载中
			{
				loadNext();
			}
		}
		
		//加载下一个资源
		private function loadNext(evt:Event=null):void
		{
			if(needLoadInfoes.length == 0)
			{
				isLoading = false;
				getDesign(_currentMoveStatus);
				return;
			}
			_currentLoadData = needLoadInfoes.pop() as DesignPartData;
			//如果加载缓存中有同名资源，则从缓存中取
			if(!DesignByteCache.hasNoCache(_currentLoadData.loadCacheName))
			{
				setPartByte(DesignByteCache.getCache(_currentLoadData.loadCacheName));
				if(needLoadInfoes.length == 0)
				{							
					isLoading = false;
					getDesign(_currentMoveStatus);
					return;
				}
			}
			
			_urlLoad.load(new URLRequest(_currentLoadData.url));
				
		}
			
		//某个资源完成下载
		private function loaded(evt:Event):void
		{
			if(_currentLoadData.loadCacheName != null)
				DesignByteCache.addToCache(_urlLoad.data, _currentLoadData.loadCacheName);
			
			setPartByte(_urlLoad.data);
			_currentLoadData = null;
			loadNext();
		}
		
		//某个资源下载失败
		private function loadFail(evt:ErrorEvent):void
		{
			if(_maxTryLoadNum > 0)
			{
				_maxTryLoadNum--;
				_urlLoad.data = null;
				_urlLoad.load(new URLRequest(_currentLoadData.url));
			}
			else
			{
				_maxTryLoadNum = 5;
				_currentLoadData = null;
				loadNext();
			}
		}
		
		//安全沙箱错误
		private function loadSecurityFail(evt:SecurityErrorEvent):void
		{
			_currentLoadData = null;
			loadNext();
			
		}
		
		private function setPartByte(byteData:ByteArray):void
		{
			switch(_currentLoadData.partName)
			{
				case "all":
					_allPartByte = byteData;
					break;
				case "head":
					_headPartByte = byteData;
					break;
				case "body":
					_bodyPartByte = byteData;
					break;
				case "leg":
					_legPartByte = byteData;
					break;
				case "feet":
					_feetPartByte = byteData;
					break;
			}
		}
	
	
		/**解压资源的byteArray数据，以获取SWF形式的资源
		 * @param moveStatus:要解压资源的移动状态
		 * @param cb:解压完成回调
		 * @param param:回调参数
		 * */
		public function getDesign(moveStatus:String, cb:Function=null, param:Object=null):void
		{
			_currentMoveStatus = moveStatus;
			designReadable = false;
			_lock = true;
			loadCallBackFun = cb;
			callBackParam = param;	
			
			getNum = 0;
			
			if(this.isAllPart())
			{
				if(_allPartByte != null)
				{
					allLoader = new Loader();
					allLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, allSwfLoaded);
					allLoader.loadBytes(_allPartByte);
				}
				else
				{
					trace("角色装饰压缩资源不存在");
				}
			}
			else
			{
				getNum = 4;
				
				if(_feetPartByte != null)
				{
					feetLoader = new Loader();
					feetLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, feetSwfLoaded);
					feetLoader.loadBytes(_feetPartByte);
				}
				else
				{
					trace("角色脚装饰压缩资源不存在");
				}
				
				if(_legPartByte != null)
				{
					legLoader = new Loader();
					legLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, legSwfLoaded);
					legLoader.loadBytes(_feetPartByte);
				}
				else
				{
					trace("角色腿装饰压缩资源不存在");
				}
				if(_bodyPartByte != null)
				{
					bodyLoader = new Loader();
					bodyLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, bodySwfLoaded);
					bodyLoader.loadBytes(_bodyPartByte);
				}
				else
				{
					trace("角色身躯装饰压缩资源不存在");
				}
				if(_headPartByte != null)
				{
					headLoader = new Loader();
					headLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, headSwfLoaded);
					headLoader.loadBytes(_headPartByte);
				}
				else
				{
					trace("角色头装饰压缩资源不存在");
				}
			}
		}
		
		//整体资源（不分部位）完成解压
		private function allSwfLoaded(evt:Event):void
		{
			if(allLoader==null || allLoader.content==null)
			{
				trace("整体资源不存在")
				return;
			}
			
			var AllClass:Class;
			try{
				AllClass = allLoader.contentLoaderInfo.applicationDomain.getDefinition(_currentMoveStatus) as Class;
			}
			catch(e:Error)
			{
				trace("获取All类错误");
				return;
			}
			if(AllClass != null)
			{
				_all = (new AllClass()) as BitmapData;
			}
			
			allLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, allSwfLoaded);
			if(_designConfigData.allPartData.bmdVectorCacheName != null)//需要缓存位图数据
			{
				if(DesignBMDCache.hasNoCache(_designConfigData.allPartData.bmdVectorCacheName))
				{
					_allBMDVector = AvatarUtils.serializationBMD(_all, _rec);
					DesignBMDCache.addToCache(_allBMDVector, _designConfigData.allPartData.bmdVectorCacheName);
				}
			}
			swfLoadedComplete();
		}
		
		//脚部资源完成解压
		private function feetSwfLoaded(evt:Event):void
		{
			if(feetLoader==null || feetLoader.content==null)
			{
				trace("资源不存在");
				return;//?这里属于不正常现象
			}
			var ResClass:Class = feetLoader.contentLoaderInfo.applicationDomain.getDefinition(_currentMoveStatus) as Class;
			_feet = new ResClass() as BitmapData;
			if(_designConfigData.feetPartData.bmdVectorCacheName != null)//需要缓存位图数据
			{
				if(DesignBMDCache.hasNoCache(_designConfigData.feetPartData.bmdVectorCacheName))
				{
					_feetBMDVector = AvatarUtils.serializationBMD(_feet, _rec);
					DesignBMDCache.addToCache(_feetBMDVector, _designConfigData.feetPartData.bmdVectorCacheName);
				}
			}
			getNum--;
			if(getNum==0)
			{
				swfLoadedComplete();
			}
		}
		
		//腿部资源完成解压
		private function legSwfLoaded(evt:Event):void
		{
			if(legLoader==null || legLoader.content==null)
			{
				trace("资源不存在")
				return;//?这里属于不正常现象
			}
			var ResClass:Class = legLoader.contentLoaderInfo.applicationDomain.getDefinition(_currentMoveStatus) as Class;
			_leg = new ResClass() as BitmapData;
			if(_designConfigData.legPartData.bmdVectorCacheName != null)//需要缓存位图数据
			{
				if(DesignBMDCache.hasNoCache(_designConfigData.legPartData.bmdVectorCacheName))
				{
					_legBMDVector = AvatarUtils.serializationBMD(_leg, _rec);
					DesignBMDCache.addToCache(_legBMDVector, _designConfigData.legPartData.bmdVectorCacheName);
				}
			}
			getNum--;
			if(getNum==0)
			{
				swfLoadedComplete();
			}
		}
		
		//身躯资源完成解压
		private function bodySwfLoaded(evt:Event):void
		{
			if(bodyLoader==null || bodyLoader.content==null)
			{
				trace("资源不存在")
				return;//?这里属于不正常现象
			}
			var ResClass:Class = bodyLoader.contentLoaderInfo.applicationDomain.getDefinition(_currentMoveStatus) as Class;
			_body = new ResClass() as BitmapData;
			if(_designConfigData.bodyPartData.bmdVectorCacheName != null)//需要缓存位图数据
			{
				if(DesignBMDCache.hasNoCache(_designConfigData.bodyPartData.bmdVectorCacheName))
				{
					_bodyBMDVector = AvatarUtils.serializationBMD(_body, _rec);
					DesignBMDCache.addToCache(_bodyBMDVector, _designConfigData.bodyPartData.bmdVectorCacheName);
				}
			}
			getNum--;
			if(getNum==0)
			{
				swfLoadedComplete();
			}
		}
		
		//头部资源完成解压
		private function headSwfLoaded(evt:Event):void
		{
			if(headLoader==null || headLoader.content==null)
			{
				trace("资源不存在")
				return;//?这里属于不正常现象
			}
			var ResClass:Class = headLoader.contentLoaderInfo.applicationDomain.getDefinition(_currentMoveStatus) as Class;
			_head = new ResClass() as BitmapData;
			if(_designConfigData.headPartData.bmdVectorCacheName != null)//需要缓存位图数据
			{
				if(DesignBMDCache.hasNoCache(_designConfigData.headPartData.bmdVectorCacheName))
				{
					_headBMDVector = AvatarUtils.serializationBMD(_head, _rec);
					DesignBMDCache.addToCache(_headBMDVector, _designConfigData.headPartData.bmdVectorCacheName);
				}
			}
			getNum--;
			if(getNum==0)
			{
				swfLoadedComplete();
			}
		}
		
		//所有资源都已经解压完成
		private function swfLoadedComplete():void
		{
			if(isAllPart())
			{
				_statusBMDVector = _allBMDVector;
			}
			else
			{
				//w 组装各部位
				
				
				
				
				
				
				
				
				
				
			}
			
			if(binaryLoadTaskArr.length == 0)
			{
				onGetStatusBMDVector();
			}
			else
				nextLoadTask();
		}
		
		//获取到当前状态位图数据序列
		private function onGetStatusBMDVector():void
		{
			if(loadCallBackFun != null)
			{
				if(callBackParam==null) 
					loadCallBackFun();
				else 
					loadCallBackFun(callBackParam);
				
				loadCallBackFun = null;
				callBackParam = null;
				release();
				_lock = false;
			}
			designReadable = true;
		}
		
		//释放解压的资源
		 private function release():void
		 {
		 	if(partsInfo == null)
		 	{
		 		trace("资源已经清空");
		 		return;
		 	}
		 	if(this.isAllPart())
		 	{
		 		allLoader.unloadAndStop(true);
		 		allLoader = null;
		 		_all = null;
		 	}
		 	else
		 	{
		 		headLoader.unloadAndStop(true);
		 		headLoader = null;
		 		_head = null;
		 		bodyLoader.unloadAndStop(true);
		 		bodyLoader =null;
		 		_body = null;
		 		legLoader.unloadAndStop(true);
		 		legLoader = null;
		 		_leg = null;
		 		feetLoader.unloadAndStop(true);
		 		feetLoader = null;
		 		_feet = null;
		 	}
		 }
		
		//开始下个加载任务
		private function nextLoadTask():void
		{
			if(binaryLoadTaskArr.length > 0)
			{
				var loadTask:Array = binaryLoadTaskArr.shift() as Array;
				this.ini(loadTask[0],loadTask[1],loadTask[2]);
			}
				
		}
		
		//装配是否为一个整体，不分部位?
		public function isAllPart():Boolean
		{
			if(partsInfo==null)
			{
				trace("错误：装配信息为空")
				return false;
			}
			
			return (partsInfo["all"]==undefined)?false:true;
		}
		
		/**
		 *获取整个身体的位图数据 
		 * @return 
		 * 
		 */		
		public function get wholeBMD():BitmapData
		{
			if(_wholeBMD == null)
			{
//tt				_wholeBMD = new BitmapData
			}
			
			return _wholeBMD;
		}
		
		public function getActionBMD():BitmapData
		{
			
			return null;//tt
		}
		
		public function get displayObj():Bitmap
		{
			return _displayObj;
		}
		
		public function get all():BitmapData
		{
			return _all;
		}
		
		public function get head():BitmapData
		{
			return _head;
		}
		
		public function get body():BitmapData
		{
			return _body;
		}
		
		public function get leg():BitmapData
		{
			return _leg;
		}
		
		public function get feet():BitmapData
		{
			return _feet;
		}
		
		public function get lock():Boolean
		{
			return _lock;
		}
		
		private function getShortName(strName:String):String
		{
			var str:String;
			if(strName.lastIndexOf("/")>0)
				str = strName.substring(strName.lastIndexOf("/")+1,strName.length);
			else
				str = strName;
			return str;
		}
		
		public function destroy():void
		{
			if(_urlLoad != null)
			{
				_urlLoad.removeEventListener(IOErrorEvent.IO_ERROR,loadFail);
				_urlLoad.removeEventListener(IOErrorEvent.DISK_ERROR,loadFail);
				_urlLoad.removeEventListener(IOErrorEvent.NETWORK_ERROR,loadFail);
				_urlLoad.removeEventListener(IOErrorEvent.VERIFY_ERROR,loadFail);
				_urlLoad.removeEventListener(ErrorEvent.ERROR,loadFail);
				_urlLoad.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,loadSecurityFail);
				_urlLoad.removeEventListener(Event.COMPLETE,loaded);
				_urlLoad = null;
			}
			
			if(partsInfo != null)
			{
				delete partsInfo["all"];
				delete partsInfo["feet"];
				delete partsInfo["leg"];
				delete partsInfo["body"];
				delete partsInfo["head"];
			}
			partsInfo = null;
		}

	}
}